 #include "hwicap.h"


 /************************** Variable Definitions *****************************/

 static XHwIcap HwIcap;

 int HwIcapReadConfigRegExample();
 u32 XHwIcap_CommandIPROG(XHwIcap *InstancePtr, u32 fpga_load_address);

 int HwIcaptest(void)
 {
 	int Status;
	u32 fpga_load_address = 0x00000000;
 	Status = XHwIcap_CommandIPROG(&HwIcap, fpga_load_address);
 	if (Status != XST_SUCCESS) {
 		xil_printf("XHwIcap_CommandIPROG Failed\r\n");
 		return XST_FAILURE;
 	}

 	xil_printf("Successfully ran Hwicap read config reg Example\r\n");
 	return XST_SUCCESS;
 }

 int InitHwIcap()
 {
 	int Status;
 	XHwIcap_Config *CfgPtr;

 	/*
 	 * Initialize the HwIcap instance.
 	 */
 	CfgPtr = XHwIcap_LookupConfig(HWICAP_DEVICEID);
 	if (CfgPtr == NULL) {
 		return XST_FAILURE;
 	}

 	Status = XHwIcap_CfgInitialize(&HwIcap, CfgPtr, CfgPtr->BaseAddress);
 	if (Status != XST_SUCCESS) {
 		return XST_FAILURE;
 	}


 	/*
 	 * Run the Self test.
 	 */
 	Status = XHwIcap_SelfTest(&HwIcap);
 	if (Status != XST_SUCCESS) {
 		return XST_FAILURE;
 	}
 	return XST_SUCCESS;
 }


 int HwIcapReadConfigRegExample()
 {
 	u32 ConfigRegData;
 	printf("Value of the Configuration Registers. \r\n\r\n");

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_CRC, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" CRC -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_FAR, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" FAR -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_FDRI, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" FDRI -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_FDRO, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" FDRO -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_CMD, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" CMD -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_CTL, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" CTL -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_MASK, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" MASK -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_STAT, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" STAT -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_LOUT, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" LOUT -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_COR, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" COR -> \t 0x%x \t\r\n", ConfigRegData);
 	}
 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_MFWR, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" MFWR -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_CBC, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" CBC -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_AXSS, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" AXSS -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_IDCODE, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" IDCODE -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_COR_1, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" COR_1 -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_CSOB, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" CSOB -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_WBSTAR, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" WBSTAR -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_TIMER, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" TIMER -> \t 0x%x \t\r\n", ConfigRegData);
 	}
 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_BOOTSTS, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" BOOTSTS -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	if (XHwIcap_GetConfigReg(&HwIcap, XHI_CTL_1, (u32 *)&ConfigRegData) ==
 		XST_SUCCESS) {
 		printf(" CTL_1 -> \t 0x%x \t\r\n", ConfigRegData);
 	}

 	printf("\r\n HwIcapReadConfigRegExample Passed Successfully.\r\n\r\n");

 	return XST_SUCCESS;
 }


 u32 XHwIcap_CommandIPROG(XHwIcap *InstancePtr, u32 fpga_load_address)
 {
 	int Status;
 	int EosRetries =0; /* Counter for checking EOS to become high */
 	u32 FrameBuffer[8];
 	u32 Index =0;

 	Xil_AssertNonvoid(InstancePtr != NULL);
 	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

 	/*
 	 * Create the data to be written to the ICAP.
 	 */
 	FrameBuffer[Index++] = XHI_DUMMY_PACKET;
 	FrameBuffer[Index++] = XHI_SYNC_PACKET;
 	FrameBuffer[Index++] = XHI_NOOP_PACKET;
 	FrameBuffer[Index++] = XHwIcap_Type1Write(XHI_WBSTAR) | 0x1;
 	FrameBuffer[Index++] = fpga_load_address;//0x00000000;
 	FrameBuffer[Index++] = XHwIcap_Type1Write(XHI_CMD) | 0x1;;
 	FrameBuffer[Index++] = 0x0000000F;
 	FrameBuffer[Index++] = XHI_NOOP_PACKET;

	printf("----------------- reconfigure fpga bit ----------------- r\n");
 	int idx;
 	for(idx=0;idx<8;idx++){
 		printf(" idx: %d -- 0x%x \t\r\n", idx, FrameBuffer[idx]);
 	}

 	/*
 	 * Check for EOS bit of Status Register. EOS bit becomes high after
 	 * ICAP completes Start up sequence. Access to ICAP should start
 	 * only after EOS bit becomes high.
 	 */

 	while((!(XHwIcap_ReadReg(InstancePtr->HwIcapConfig.BaseAddress,
 			XHI_SR_OFFSET)& XHI_SR_EOS_MASK))) {

 		if(EosRetries < XHI_MAX_RETRIES) {
 			EosRetries++;
 		}
 		else {
 	   		return XST_FAILURE;
 		}

 	}


 	/*
 	 * Write the data to the FIFO and intiate the transfer of data present
 	 * in the FIFO to the ICAP device.
 	 */
 	Status = XHwIcap_DeviceWrite(InstancePtr, &FrameBuffer[0], Index);
 	if (Status != XST_SUCCESS)  {
 		return XST_FAILURE;
 	}

 	while (XHwIcap_IsDeviceBusy(InstancePtr) != FALSE);
 	while ((XHwIcap_ReadReg(InstancePtr->HwIcapConfig.BaseAddress,
 			XHI_CR_OFFSET)) & XHI_CR_WRITE_MASK);


 	return XST_SUCCESS;
 }


int HwIcapLoadBit(u32 fpga_load_address)
{
	int Status;
	Status = XHwIcap_CommandIPROG(&HwIcap, fpga_load_address);
	if (Status != XST_SUCCESS) {
		xil_printf("HwIcapLoadBit Failed\r\n");
		return XST_FAILURE;
	}

	xil_printf("Successfully HwIcapLoadBit\n");
	return XST_SUCCESS;
}